package opc.read.sycread;

import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows;
import opc.read.utils.MyCopyOnWriteMap;
import opc.read.utils.ReadTItem2;
import opc.read.utils.WriterFile;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.*;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description:  早期写的仙鹤的，信息来源是properties文件
 * @author: liyuan
 * @data 2021-01-06 10:21
 */
public class ByRead {
    public static void DemoAPI() throws IOException {

        Map<String, String> dataSources = ReadTItem2.loadFile();

        final ConnectionInformation ci = new ConnectionInformation();
        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ci.setHost(dataSources.get("host"));
        ci.setDomain(dataSources.get("domain"));
        ci.setUser(dataSources.get("user"));
        ci.setPassword(dataSources.get("password"));
        ci.setClsid(dataSources.get("clsid"));
        final Map<String, Object> result = new LinkedHashMap<String, Object>();
        final MyCopyOnWriteMap<String, Object> resultNew = new MyCopyOnWriteMap<String, Object>(new LinkedHashMap<String, Object>());
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        final AutoReconnectController autoReconnectController = new AutoReconnectController(server);
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        try {
            // connect to server
            autoReconnectController.connect();
            int size = Integer.parseInt(dataSources.get("len"));
            final AccessBase access = new SyncAccess(server, 1000);
//            final AccessBase access = new Async20Access(server, 1000,false);
            for (int i = 0; i < size; i++) {
                //设置group对象
                String groupName = dataSources.get("deviceName" + i);
                Group group = null;
                group = server.addGroup(groupName);
                group.setActive(true);
                /***
                 *  构造信号集合“：resultItemMap   {	"CST28214": "", 	"SP28214_RD": ""}
                 */
                Map<String, Object> newMap = new LinkedHashMap<String, Object>();
                String[] split = dataSources.get("deviceName" + i + ".deviceItem").split(",");
                for (int j = 0; j < split.length; j++) {
                    newMap.put(split[j], null);
                    split[j] = "xianhe.设备 1." + split[j];
                }
                Map<String, Item> itemMap = group.addItems(split);
                result.put(groupName, itemMap);
                resultNew.put(groupName, newMap);
            }
            //新开线程开始读取
            scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    String s = JSON.toJSONString(resultNew);
                    System.out.println("--json---");
                    System.out.println(s);
                    WriterFile.writeTxtFile(s, new File("d:/ProDataAccess/xianhe/data/file3/" + formatter.format(new Date()) + ".txt"), "utf-8");
                }
            }, 2000, 1000, TimeUnit.MILLISECONDS);
            //将date放在resultNew最前面
            resultNew.put("date", System.currentTimeMillis());
            while (true) {
                //组
                resultNew.put("date", System.currentTimeMillis());
                for (final String groupName : result.keySet()) {
                    Map<String, Item> itemMap = (Map<String, Item>) result.get(groupName);
                    //组内部的读取信号
                    for (Map.Entry<String, Item> map : itemMap.entrySet()) {
                        if (map.getValue() instanceof Item) {
                            //读取单个数据的代码
                            access.addItem(map.getValue().getId(), new DataCallback() {
                                @SneakyThrows
                                @Override
                                public void changed(Item item, ItemState state) {
                                    System.out.println("--changed---");
                                    if (state.getValue().getObject() instanceof Double || state.getValue().getObject() instanceof Boolean) {
                                        Map<String, Object> itemMap = (Map<String, Object>) resultNew.get(groupName);
                                        itemMap.put(item.getId().split("\\.")[2], state.getValue().getObject());
                                    }

                                }
                            });
                        }

                    }
                    /***
                     for (Map.Entry<String, Item> map : itemMap.entrySet()) {
                     if (map.getValue() instanceof Item) {
                     Item item = map.getValue();
                     Object object = item.read(false).getValue().getObject();
                     ((Map<String, Object>) resultNew.get(groupName)).put(item.getId().split("\\.")[2], object);
                     }
                     }
                     ****/
                }
                access.bind();
                Thread.sleep(100);
                access.unbind();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
